package gspushmq.v1.produce.job.sys;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import ggframework.mongodb.BasicDBObject;
import ggframework.mongodb.DBCollection;
import ggframework.mongodb.DBCursor;
import ggframework.mongodb.DBObject;
import gspushmq.model.DataBase;
import gspushmq.model.MessageType;
import gspushmq.model.UserType;
import gspushmq.util.MongoUtil;
import gspushmq.util.ToolsUtil;
import gspushmq.v1.produce.GGDataStorage;
import gspushmq.v1.produce.job.core.GGServiceJob;
import gspushmq.v1.save.SaveMassRecord;



public class GGValuationJob extends GGServiceJob{
	@Override
	protected String setJobName(Map<String, Object> params) {
		return "盈利能力估值模式";
	}

	@Override
	public void doServiceJob(Map<String, Object> args) {
		info();
	}
	
	public void info(){
		DBCollection collection = MongoUtil.getGGStockBaseCollection("gg_security_code");
		DBObject query = new BasicDBObject("type", 1);
		DBObject fields = new BasicDBObject("_id", 0);
		fields.put("code", 1);
		DBCursor cursor = collection.find(query, fields);
		List<String> stockCodes = new ArrayList<String>();
		while (cursor.hasNext()) {
			DBObject o = (DBObject) cursor.next();
			stockCodes.add(o.getString("code"));
		}
		cursor.close();
		
		collection = MongoUtil.getGGStockCollection("report_stock_b4");
    	query = new BasicDBObject("symbol", new BasicDBObject("$in", stockCodes));
    	BasicDBObject field = new BasicDBObject("_id", 0).append("symbol", 1).append("sname", 1).append("tclose", 1)
    			.append("y0eps", 1).append("y1eps", 1).append("y2eps", 1).append("y3eps", 1)
				.append("y0pe", 1).append("y1pe", 1).append("y2pe", 1).append("y3pe", 1)
				.append("y0roe", 1).append("y1roe", 1).append("y2roe", 1).append("y3roe", 1)
				.append("tcap", 1).append("mcap", 1).append("radar_flag", 1)
				.append("y0contype", 1).append("y1contype", 1).append("y2contype", 1).append("y3contype", 1)
				.append("y0pb", 1).append("y1pb", 1).append("y2pb", 1).append("y3pb", 1)
				.append("y0profittb", 1).append("y1profittb", 1).append("y2profittb", 1).append("y3profittb", 1)
				.append("y0ckprofit", 1).append("y1ckprofit", 1).append("y2ckprofit", 1).append("y3ckprofit", 1)
				.append("y0ps", 1).append("y1ps", 1).append("y2ps", 1).append("y3ps", 1)
				.append("y0profit", 1).append("y1profit", 1).append("y2profit", 1).append("y3profit", 1);
    	cursor = collection.find(query, field);
    	
    	List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
    	while (cursor.hasNext()) {
			DBObject o = cursor.next();
			String code = o.getString("symbol");
			String name = o.getString("sname");
			Map<String, Object> map = o.toMap();
			map.put("stock_code", code);
			map.put("stock_name", name);
			map.remove("symbol");
			map.remove("sname");
			resultList.add(map);
		}
    	cursor.close();
    	Map<String,Map<String,Object>> m1 = new HashMap<String,Map<String,Object>>();
    	Map<String, Set<String>> newMap = new HashMap<>();
    	for (Map<String, Object> map : resultList) {
			String stock_code = map.get("stock_code").toString();
			map.put("y0pe", map.get("y0pe") == null ? null : ToolsUtil.scal(unifyPe(Double.parseDouble(map.get("y0pe").toString())), 2));
			map.put("y1pe", map.get("y1pe") == null ? null : ToolsUtil.scal(unifyPe(Double.parseDouble(map.get("y1pe").toString())), 2));
			map.put("y2pe", map.get("y2pe") == null ? null : ToolsUtil.scal(unifyPe(Double.parseDouble(map.get("y2pe").toString())), 2));
			map.put("y3pe", map.get("y3pe") == null ? null : ToolsUtil.scal(unifyPe(Double.parseDouble(map.get("y3pe").toString())), 2));
			
			map.put("y0roe", map.get("y0roe") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y0roe").toString()) * 100), 2));
            map.put("y1roe", map.get("y1roe") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y1roe").toString()) * 100), 2));
            map.put("y2roe", map.get("y2roe") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y2roe").toString()) * 100), 2));
            map.put("y3roe", map.get("y3roe") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y3roe").toString()) * 100), 2));
            
            map.put("y0profittb", map.get("y0profittb") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y0profittb").toString()) * 100), 2));
            map.put("y1profittb", map.get("y1profittb") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y1profittb").toString()) * 100), 2));
            map.put("y2profittb", map.get("y2profittb") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y2profittb").toString()) * 100), 2));
            map.put("y3profittb", map.get("y3profittb") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y3profittb").toString()) * 100), 2));
            
            map.put("y0ckprofit", map.get("y0ckprofit") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y0ckprofit").toString()) / 100), 2));
            map.put("y1ckprofit", map.get("y1ckprofit") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y1ckprofit").toString()) / 100), 2));
            map.put("y2ckprofit", map.get("y2ckprofit") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y2ckprofit").toString()) / 100), 2));
            map.put("y3ckprofit", map.get("y3ckprofit") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y3ckprofit").toString()) / 100), 2));
            
            map.put("y0profit", map.get("y0profit") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y0profit").toString()) / 1000000), 2));
            map.put("y1profit", map.get("y1profit") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y1profit").toString()) / 1000000), 2));
            map.put("y2profit", map.get("y2profit") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y2profit").toString()) / 1000000), 2));
            map.put("y3profit", map.get("y3profit") == null ? null : ToolsUtil.scal((Double.parseDouble(map.get("y3profit").toString()) / 1000000), 2));
            
            int y0contype = 1;
            int y1contype = 1;
            int y2contype = 1;
            int y3contype = 1;
            if (map.get("y0contype") != null) {
            	y0contype = Integer.parseInt(map.get("y0contype").toString().substring(map.get("y0contype").toString().length() - 1));
            }
            if (map.get("y1contype") != null) {
            	y1contype = Integer.parseInt(map.get("y1contype").toString().substring(map.get("y1contype").toString().length() - 1));
            }
            if (map.get("y2contype") != null) {
            	y2contype = Integer.parseInt(map.get("y2contype").toString().substring(map.get("y2contype").toString().length() - 1));
            }
            if (map.get("y3contype") != null) {
            	y3contype = Integer.parseInt(map.get("y3contype").toString().substring(map.get("y3contype").toString().length() - 1));
            }
            map.put("y0contype", y0contype);
            map.put("y1contype", y1contype);
            map.put("y2contype", y2contype);
            map.put("y3contype", y3contype);
            m1.put(stock_code, map);
            
            Set<String> keySet = map.keySet();
			Set<String> newSet = new HashSet<>();
			for(String s: keySet){
				Object obj = map.get(s);
				if(obj!= null){
					newSet.add(obj.toString());
				}
			}
			newMap.put(map.get("stock_code").toString(), newSet);
		}
    	
		
		MessageType messType = new MessageType();
		messType.setMq_type("sys");
		messType.setMq_sub_type("valuation");
		messType.setUser_type(UserType.ALL);
		
		DataBase dataBase = GGDataStorage.BaseMap.get(messType);
		if (dataBase == null) {
			dataBase = new DataBase();
			GGDataStorage.BaseMap.put(messType, dataBase);
			dataBase.setValuationMap(m1);
			dataBase.setValuationSetMap(newMap);
		} else {
			Map<String, Map<String, Object>> lastMtMap = dataBase.getValuationMap();
			Map<String, Set<String>> lastMystockTagsSetMap = dataBase.getValuationSetMap();
			List<String> codeList = new ArrayList<String>();
			for (Entry<String, Set<String>> en : lastMystockTagsSetMap.entrySet()) {
				String code = en.getKey();
				Set<String> set = en.getValue();
				if (newMap != null && !newMap.isEmpty() && newMap.get(code) != null && !newMap.get(code).isEmpty()) {
					// 对比两次数据key值是否有变化 拿到有变化code
					Set<String> newSet = newMap.get(code);
					for (String s : set) {
						newSet.remove(s);
					}
					if (newSet.size() > 0) {
						codeList.add(code);
					}
				}
			}
			
			List<Map<String, Object>> tagsList = new ArrayList<>();
			// 对比数据
			for (Entry<String, Map<String, Object>> en : m1.entrySet()) {
				String code = en.getKey();
				if (!codeList.contains(code)) {
					continue;
				}
				String fullCode = null;
				if (!code.startsWith("60")
						&& !code.startsWith("90")) {
					fullCode = "sz" + code;
				} else {
					fullCode = "sh" + code;
				}
				Map<String, Object> map = en.getValue();
				
				Map<String, Object> lastMap = lastMtMap.get(code);
				
				Map<String, Object> tMap = new HashMap<>();
				//遍历新数据的股票字段和该股票旧字段进行比较
				Iterator<Entry<String, Object>> iterator = map.entrySet().iterator();
				while (iterator.hasNext()) {
					Entry<String, Object> o = iterator.next();
					String fie = o.getKey();
					Object newsValue = o.getValue();
					Object lastValue = lastMap.get(fie);
					if(newsValue == null || lastValue == null){
						continue;
					}
					if(!newsValue.toString().equals(lastValue.toString())){
						tMap.put(fie, newsValue);
						tMap.put("full_code", fullCode);
					}
				}
				tagsList.add(tMap);
				tMap = new HashMap<>();
			}
//			DataMessage dm = new DataMessage();
//			dm.setUserType(UserType.ALL);
//			dm.setMqType("sys");
//			dm.setMqSubType("valuation");
//			dm.setValuationList(tagsList);
			
			SaveMassRecord.handlerData(messType, tagsList, "盈利估值模式");
//			GGDataStorage.MessageMap.put(messType, dm);
//			GGSubscribe.activeQueue.add(messType);
			
			dataBase.setValuationMap(m1);
			dataBase.setValuationSetMap(newMap);
		}
	}
	
	public static Double unifyPe(Double pe) {
        if (pe != null && (pe < 0 || pe > 100)) {
            return 100d;
        }
        return pe;
    }
}
